/*
 * Copyright 2005-2013 finalist.cn. All rights reserved.
 * Support: http://www.finalist.cn
 * License: http://www.finalist.cn/license
 */
package com.finalist.plugin.bestpayUnify;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import com.finalist.entity.Payment;
import com.finalist.entity.PluginConfig;
import com.finalist.plugin.PaymentPlugin;

/**
 * Plugin - 翼支付[统一收银台]
 * 
 * @author Finalist IT Group
 * @version 3.0
 */
@Component("bestpayUnifyPlugin")
public class BestpayUnifyPlugin extends PaymentPlugin {
	
	private static Logger log  = Logger.getLogger(BestpayUnifyPlugin.class);
//	private static final String KEY = "8F3E2F8EDB2B028072ACE8A3ED7DC42642FE07075E6E3284";//乐语通信KEY
//	private static final String KEY = "D05422029ACD3C3771ABDD19AFBFCF9E91CFAA2AFFF00E32";//乐语商贸2KEY
	//private static final String TRAN_KEY = "447846"; // 退款时用这个 key
//	private static final String PARTNER_ID = "02110201020093000";//乐语通信
//	private static final String PARTNER_ID = "02110104040092000";//乐语商贸2
	
	private static final String KEY = "E4C3813E97DF20FC5FF8F94E1A6A19352530280094217553";//乐语商贸2KEY
	private static final String PARTNER_ID = "02110109020606000";//乐语商贸2
	@Override
	public String getName() {
		return "翼支付";
	}

	@Override
	public String getVersion() {
		return "1.0";
	}

	@Override
	public String getAuthor() {
		return "finalist";
	}

	@Override
	public String getSiteUrl() {
		return "http://www.finalist.cn";
	}

	@Override
	public String getInstallUrl() {
		return "bestpay_unify/install.jhtml";
	}

	@Override
	public String getUninstallUrl() {
		return "bestpay_unify/uninstall.jhtml";
	}

	@Override
	public String getSettingUrl() {
		return "bestpay_unify/setting.jhtml";
	}

	@Override
	public String getRequestUrl() {
		return "https://webpaywg.bestpay.com.cn/payWebUnify.action";
	}

	@Override
	public RequestMethod getRequestMethod() {
		return RequestMethod.get;
	}

	@Override
	public String getRequestCharset() {
		return "UTF-8";
	}

	@Override
	public Map<String, Object> getParameterMap(String sn, String description, HttpServletRequest request) {
		Payment payment = getPayment(sn);
		Map<String, Object> parameterMap = new LinkedHashMap<String, Object>();
		parameterMap.put("ACCORGCODE", "");
		parameterMap.put("MERCHANTID", PARTNER_ID); // 商户号
		//parameterMap.put("SUBMERCHANTID", ""); // 子商户号
		parameterMap.put("ORDERSEQ", sn);
		parameterMap.put("ORDERREQTRANSEQ", sn);
		parameterMap.put("ORDERDATE", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
		parameterMap.put("ORDERAMOUNT", payment.getAmount().multiply(new BigDecimal(100)).setScale(0).toString());
		parameterMap.put("PRODUCTAMOUNT", payment.getAmount().multiply(new BigDecimal(100)).setScale(0).toString());
		parameterMap.put("ATTACHAMOUNT", "0");
		parameterMap.put("CURTYPE", "RMB");
		parameterMap.put("ENCODETYPE", "1");
		parameterMap.put("MERCHANTURL", getNotifyUrl(sn, NotifyMethod.sync));
		parameterMap.put("BACKMERCHANTURL", getNotifyUrl(sn, NotifyMethod.async));
		parameterMap.put("ATTACH", "shopxx");
		parameterMap.put("BUSICODE", "0001");
		parameterMap.put("PRODUCTNO", "");
		parameterMap.put("PRODUCTID", "08");
		parameterMap.put("TMNUM", "");
		parameterMap.put("CUSTOMERID", "");
		parameterMap.put("PRODUCTDESC", "shopping");
		parameterMap.put("CLIENTIP", request.getLocalAddr());
		parameterMap.put("PAYMENTWAY", "01");

		parameterMap.put("MAC", generateMac(parameterMap));
		return parameterMap;
	}

	@Override
	public boolean verifyNotify(String sn, NotifyMethod notifyMethod, HttpServletRequest request) {
		Payment payment = getPayment(sn);
		Map<String, Object> parameterMap = new LinkedHashMap<String, Object>();
//		parameterMap.put("UPTRANSEQ", request.getParameter("UPTRANSEQ"));
//		parameterMap.put("MERCHANTID",PARTNER_ID);
//		parameterMap.put("ORDERID", request.getParameter("ORDERSEQ"));
//		parameterMap.put("PAYMENT", request.getParameter("ORDERAMOUNT"));
//		parameterMap.put("RETNCODE", request.getParameter("RETNCODE"));
//		parameterMap.put("RETNINFO", request.getParameter("RETNINFO"));
//		parameterMap.put("PAYDATE", request.getParameter("TRANDATE"));
//		parameterMap.put("KEY", KEY);
		
		parameterMap.put("UPTRANSEQ", request.getParameter("UPTRANSEQ"));
		parameterMap.put("TRANDATE", request.getParameter("TRANDATE"));
		parameterMap.put("RETNCODE", request.getParameter("RETNCODE"));
		parameterMap.put("RETNINFO", request.getParameter("RETNINFO"));
		parameterMap.put("ORDERREQTRANSEQ", request.getParameter("ORDERREQTRANSEQ"));
		parameterMap.put("ORDERSEQ", request.getParameter("ORDERSEQ"));
		parameterMap.put("ORDERAMOUNT", request.getParameter("ORDERAMOUNT"));
		parameterMap.put("PRODUCTAMOUNT", request.getParameter("PRODUCTAMOUNT"));
		parameterMap.put("ATTACHAMOUNT", request.getParameter("ATTACHAMOUNT"));
		parameterMap.put("CURTYPE", request.getParameter("CURTYPE"));
		parameterMap.put("ENCODETYPE", request.getParameter("ENCODETYPE"));
		parameterMap.put("BANKID", request.getParameter("BANKID"));
		parameterMap.put("ATTACH", request.getParameter("ATTACH"));
		parameterMap.put("UPREQTRANSEQ", request.getParameter("UPREQTRANSEQ"));
		parameterMap.put("UPBANKTRANSEQ", request.getParameter("UPBANKTRANSEQ"));
		parameterMap.put("PRODUCTNO", request.getParameter("PRODUCTNO"));
		
		log.info("verify sign============" + request.getParameter("SIGN"));
		if (generateSign(parameterMap).equals(request.getParameter("SIGN")) && sn.equals(request.getParameter("ORDERSEQ")) && "0000".equals(request.getParameter("RETNCODE")) && payment.getAmount().multiply(new BigDecimal(100)).compareTo(new BigDecimal(request.getParameter("ORDERAMOUNT"))) == 0) {
			return true;
		}else{
			log.info(generateSign(parameterMap));
			log.info(request.getParameter("ORDERSEQ"));
			log.info(request.getParameter("RETNCODE"));
			log.info(new BigDecimal(request.getParameter("ORDERAMOUNT")));
			log.info(payment.getAmount().multiply(new BigDecimal(100)));
		}
		return false;
		
//		if (generateSign(parameterMap).equals(request.getParameter("SIGN"))){
//				if( sn.equals(request.getParameter("ORDERSEQ")) ){
//						if("0000".equals(request.getParameter("RETNCODE")) ){
//							if( payment.getAmount().multiply(new BigDecimal(100)).compareTo(new BigDecimal(request.getParameter("ORDERAMOUNT"))) == 0) {
//			return true;
//			}else{
//				System.out.println(payment.getAmount().multiply(new BigDecimal(100)));
//				System.out.println(new BigDecimal(request.getParameter("ORDERAMOUNT")));
//			}
//							}else{
//								System.out.println(request.getParameter("RETNCODE"));
//							}
//		}else{
//			System.out.println(request.getParameter("ORDERSEQ"));
//		}
//		}else{
//			System.out.println(generateSign(parameterMap));
//		}
//		return false;
	}

	@Override
	public String getNotifyMessage(String sn, NotifyMethod notifyMethod, HttpServletRequest request) {
		if (notifyMethod == NotifyMethod.async) {
			return "UPTRANSEQ_" + request.getParameter("UPTRANSEQ");
		}
		return null;
	}

	@Override
	public Integer getTimeout() {
		return 21600;
	}

	/**
	 * 生成签名
	 * 
	 * @param parameterMap  参数
	 * @return 签名
	 */
	private String generateMac(Map<String, Object> parameterMap) {
		StringBuilder sb = new StringBuilder();
		sb.append("MERCHANTID=" + PARTNER_ID);
		sb.append("&ORDERSEQ=" + parameterMap.get("ORDERSEQ"));
		sb.append("&ORDERREQSEQ=" + parameterMap.get("ORDERREQTRANSEQ"));
		sb.append("&ORDERDATE=" + parameterMap.get("ORDERDATE"));
		sb.append("&ORDERAMOUNT=" + parameterMap.get("ORDERAMOUNT"));
		sb.append("&ACCORGCODE=" + parameterMap.get("ACCORGCODE"));
		sb.append("&FRONTMERCHANTURL=" + parameterMap.get("MERCHANTURL"));
		sb.append("&BACKMERCHANTURL=" + parameterMap.get("BACKMERCHANTURL"));
		sb.append("&ATTACH=" + parameterMap.get("ATTACH"));
		sb.append("&BUSITYPE=" + parameterMap.get("BUSICODE"));
		sb.append("&PRODUCTNO=" + parameterMap.get("PRODUCTNO"));
		sb.append("&CLIENTIP=" + parameterMap.get("CLIENTIP"));
		sb.append("&KEY=" + KEY);
		
		log.info("mac src===" + sb.toString());
		log.info("mac dest===" + CryptTool.md5Digest(sb.toString()));
		return CryptTool.md5Digest(sb.toString());
	}
	
	private String generateSign(Map<String, Object> parameterMap) {
//		PluginConfig pluginConfig = getPluginConfig();
		
		StringBuilder sb = new StringBuilder();
		sb.append("UPTRANSEQ=" + parameterMap.get("UPTRANSEQ"));
//		sb.append("&MERCHANTID=" + pluginConfig.getAttribute("partner"));
		sb.append("&MERCHANTID=" + PARTNER_ID);
		sb.append("&ORDERID=" + parameterMap.get("ORDERSEQ"));
		sb.append("&PAYMENT=" + parameterMap.get("ORDERAMOUNT"));
		sb.append("&RETNCODE=" + parameterMap.get("RETNCODE"));
		sb.append("&RETNINFO=" + parameterMap.get("RETNINFO"));
		sb.append("&PAYDATE=" + parameterMap.get("TRANDATE"));
		sb.append("&KEY=" + KEY);
		
		log.info("verify src===" + sb.toString());
		log.info("verify dest===" + CryptTool.md5Digest(sb.toString()));
		
		return CryptTool.md5Digest(sb.toString());
	}

}